﻿using System.Diagnostics;
using System.Runtime.InteropServices;
using JasLib.Interop.Win32;

namespace JasLib.Interop
{
    /**********************************************************************************************/
    /// <summary>
    /// Marshals a struct from a byte buffer while keeping track of exactly where you found it.
    /// </summary>
    [DebuggerDisplay("{_marshaledCopy.GetType().Name,nq} ({Size} marshaled bytes)")]
    internal class StructLocatedInBuffer<T> where T : struct
    {
        public byte[] _buffer;
        public long _lOffset;
        public T _marshaledCopy;

        public StructLocatedInBuffer(byte[] buffer, long lOffset)
        {
            _buffer = buffer;
            _lOffset = lOffset;
            Read();
            return;
        }

        public long Size
        {
            get { return MarshalHelper.SizeOf<T>(); }
        }

        public void Read()
        {
            unsafe
            {
                fixed (byte* pBuffer = _buffer)
                    _marshaledCopy = MarshalHelper.PtrToStructure<T>((UINT_PTR)pBuffer + _lOffset);
            }
            return;
        }

        public void Write()
        {
            unsafe
            {
                fixed (byte* pBuffer = _buffer)
                    Marshal.StructureToPtr(_marshaledCopy, (UINT_PTR)pBuffer + _lOffset, false);
            }
            return;
        }

        public StructLocatedInBuffer<T> NextInArray()
        {
            return new StructLocatedInBuffer<T>(_buffer, _lOffset + MarshalHelper.SizeOf<T>());
        }
    }

}
